<script setup lang="ts">
import {
  ExcelDomain,
  ImportRecordVO,
  Permission,
  Result,
  TableDetailedVO,
  TableFieldVO,
  UserBO,
  UserVO
} from "~/api/responseResult";
import {DataImportBO, TableInfo} from "~/api/requestInstance";
import vPinyin from '~/utils/pinyin'
import {
  createTable,
  dataImport,
  getIdentityByTable,
  saveTablePermission,
  tableDetailed,
  updateTable
} from "~/api/warehouse";
import {ElMessage} from "element-plus";


interface ImportState {
  active: number,
  importRecordVO: ImportRecordVO,
  excelDomain: ExcelDomain,
  tableInfo: TableInfo,
  fieldInfo: Map<number, TableFieldVO>,
  permission: Permission,
  administrators: Array<UserVO>,
  ordinaryUser: Array<UserVO>,
  // CREATE 新建 IMPORT 导入
  operationType: 'CREATE' | 'IMPORT',
  importMode: 'ADD' | 'UPDATE' | 'ADD_UPDATE',
  oldTableFieldVOMap: any,
  // 权限 1 管理员 2 普通用户 3 无权限
  identity: number
}

const refSelectSheet = ref(null);
const refTable = ref(null);
const refPermission = ref(null);

const props = defineProps<{ table: string }>()

let tableInfo = (): TableInfo => {
  return {
    tableName: '',
    tableApi: '',
    tableClassifyPid: '',
  } as TableInfo
}
const excelDomain = (): ExcelDomain => {
  return {
    sheetName: '',
    maxColumn: 0,
    tableHead: [],
    tableData: [],
    listMap: []
  } as ExcelDomain
}
const permission = (): Permission => {
  return {
    administrators: [],
    ordinaryUsers: [],
    departmentAndPosition: false,
    departments: [],
    positions: [],
  } as Permission
}
let state: ImportState = reactive({
  active: 0,
  importRecordVO: {
    pid: '',
    originalFileUrl: '',
    sheetData: {},
  },
  tableInfo: tableInfo(),
  fieldInfo: new Map(),
  excelDomain: excelDomain(),
  permission: permission(),
  administrators: [],
  ordinaryUser: [],
  operationType: 'CREATE',
  oldTableFieldVOMap: {},
  importMode: 'ADD_UPDATE',
  identity: 2
})

const router = useRouter()

const uploadSuccess = (res: ImportRecordVO) => {
  state.importRecordVO = res
  if (!state.tableInfo.tableName) {
    state.tableInfo.tableName = res.fileName
  }
  nextStep()
}

const beforeUpload = () => {
  if (state.active === 0) {
    state.tableInfo = tableInfo()
    state.fieldInfo = new Map<number, TableFieldVO>()
    state.excelDomain = excelDomain()
    state.permission = permission()
    state.administrators = []
    state.ordinaryUser = []
    state.importMode = 'ADD_UPDATE'
    state.identity = 2
  }
}

const getExcelDomain = (): boolean => {
  if (state.active === 1) {
    const excelDomain: ExcelDomain = refSelectSheet.value.getExcelDomain()
    if (state.excelDomain.sheetName !== excelDomain.sheetName) {
      // 重复表头判断
      for (let excelField of excelDomain.tableHead) {
        const arr: any[] = []
        excelDomain.tableHead.forEach(item => {
          if (item.value && item.value === excelField.value) {
            arr.push(item)
          }
        })
        if (arr.length > 1) {
          ElMessage({
            message: "不可以包含重复表头",
            type: 'error',
            duration: 5 * 1000
          })
          return false
        }
        if (excelField.value != '' && !isNaN(excelField.value)) {
          ElMessage({
            message: "列头不可以是纯数字",
            type: 'error',
            duration: 5 * 1000
          })
          return false
        }
      }
      // 判断字段是否全部匹配
      if (state.operationType === 'IMPORT') {
        // 字段可以不按照顺序
        // for (const key in state.oldTableFieldVOMap) {
        //   let on: boolean = true
        //   for (let excelField of excelDomain.tableHead) {
        //     if (state.oldTableFieldVOMap[key].fieldName === excelField.value) {
        //       on = false
        //       break
        //     }
        //   }
        //   if (on) {
        //     // 不包含原有sheet
        //     ElMessage({
        //       message: "模板匹配错误，缺少字段",
        //       type: 'error',
        //       duration: 5 * 1000
        //     })
        //     return false
        //   }
        // }


        // 字段和列顺序都要一致
        let i: number = 0;
        let on: boolean = true
        for (const key in state.oldTableFieldVOMap) {
          const json:TableFieldVO = state.oldTableFieldVOMap[key]
          const item:any = excelDomain.tableHead[json.columnNo]
          if (item) {
            if (json.fieldName !== item.value) {
              on = false
              break
            }
          } else {
            on = false
            break
          }
          i++
        }
        if (!on) {
          // 不包含原有sheet
          ElMessage({
            message: "模板匹配错误",
            type: 'error',
            duration: 5 * 1000
          })
          return false
        }
      }


      const fieldInfo: Map<number, TableFieldVO> = new Map<number, TableFieldVO>()
      for (let index: number = 0; index <= excelDomain.maxColumn; index++) {
        excelDomain.tableHead.forEach(excelField => {
          if (excelField.column === index) {
            if (excelField.value !== '') {
              const field: TableFieldVO = state.oldTableFieldVOMap[excelField.value]
              if (field) {
                fieldInfo.set(index, field)
              } else {
                fieldInfo.set(index, {
                  pid: '',
                  fieldName: excelField.value,
                  fieldApi: 'field_'+excelField.column,
                  fieldType: state.operationType === 'CREATE' ? 'text' : 'NotUsed',
                  notNull: false,
                  decimalLength: 2,
                  only: false,
                  defaultValue: '',
                  columnNo: excelField.column
                })
              }
            }
          }
        })
      }
      state.excelDomain = excelDomain
      state.fieldInfo = fieldInfo
      return true
    } else {
      return true
    }
  } else {
    return true
  }
}

const getTableInfo = (verification: boolean): boolean => {
  let on: boolean = true
  if (state.active === 2) {
    const table: { tableInfo: TableInfo; fieldInfo: Map<number, TableFieldVO>; importMode: 'ADD' | 'UPDATE' | 'ADD_UPDATE' } | null = refTable.value.getTableInfo(verification)
    if (table !== null) {
      state.tableInfo = table.tableInfo
      state.fieldInfo = table.fieldInfo
      state.importMode = table.importMode
    } else {
      on = false
    }
  }
  return on
}

const getPermission = (verification: boolean): boolean => {
  let on: boolean = true
  if (state.active === 3) {
    const permissionInfo: { permission: Permission; administrators: Array<UserVO>; ordinaryUser: Array<UserVO> } | null = refPermission.value.getPermission(verification);
    if (permissionInfo !== null) {
      state.permission = permissionInfo.permission
      state.administrators = permissionInfo.administrators
      state.ordinaryUser = permissionInfo.ordinaryUser
    } else {
      on = false
    }
  }
  return on
}

const nextStep = () => {
  let on = getExcelDomain()
  let on1 = getTableInfo(true)
  let on2 = getPermission(true)
  if (on && on1 && on2) {
    state.active = state.active + 1
  }

}
const upperStep = () => {
  let on1 = getTableInfo(false)
  let on2 = getPermission(false)
  if (on1 && on2) {
    state.active = state.active - 1
    beforeUpload()
  }
}

const preservation = () => {
  let on = true
  if (state.active === 2) {
    on = getTableInfo(true)
  } else if (state.active === 3) {
    on = getPermission(true)
  }
  if (on) {
    saveTable()
  }
}

const saveTable = async () => {
  const json: any = {...state.tableInfo}
  json.tablePid = props.table;
  let fieldList: Array<TableFieldVO> = []
  state.fieldInfo.forEach((item: TableFieldVO) => {
    if (item.fieldType !== 'NotUsed') {
      fieldList.push(item)
    }
  })
  json.fieldList = fieldList
  if (state.operationType === 'CREATE') {
    // 新建
    const userInfo: UserBO = JSON.parse(<string>localStorage.getItem("user"))
    json.tableName = json.tableName + "_" + userInfo.departmentName + "_" + userInfo.realName
    const res: Result<any> = await createTable(json)
    if (res.success) {
      // 建表成功 保存表权限
      const on = await savePermission()
      if (on) {
        // 权限建表成功
        await dataImportStart()
      }
    }
  } else if (state.operationType === 'IMPORT') {
    //导入
    // 修改表字段及索引信息
    const res: Result<any> = await updateTable(json)
    if (res.success) {
      // 修改表成功
      await dataImportStart()
    }
  }

}

const dataImportStart = async () => {
  const json: DataImportBO = {
    importPid: state.importRecordVO.pid,
    importMode: state.importMode,
    sheetName: state.excelDomain.sheetName,
  }
  const res: Result<any> = await dataImport(json)
  if (res.success) {
    await router.push("/import/result/" + state.importRecordVO.pid);
  }
}

const savePermission = async () => {
  const json: any = {};
  const permission: Permission = JSON.parse(JSON.stringify(state.permission))
  json.tablePid = props.table;
  json.administrators = permission.administrators.toLocaleString();
  json.ordinaryUsers = permission.ordinaryUsers.toLocaleString();
  json.positions = permission.positions.toLocaleString();
  json.departmentAndPosition = permission.departmentAndPosition.toLocaleString();
  json.departments = permission.departments.toLocaleString()
  const res: Result<any> = await saveTablePermission(json)
  return res.success
}

const initState = async () => {
  const res: Result<TableDetailedVO> = await tableDetailed({tablePid: props.table})
  if (res.success && res.data) {
    state.operationType = 'IMPORT'
    tableInfo = () => {
      return res.data.tableVO
    }
    state.oldTableFieldVOMap = res.data.tableFieldVOMap;
    beforeUpload()
    const res1: Result<number> = await getIdentityByTable({tablePid: props.table})
    if (res1.success) {
      state.identity = res1.data
    }

  }
}


initState()

defineExpose({
  props,
  refTable,
  refPermission,
  refSelectSheet,
  uploadSuccess,
  upperStep,
  getTableInfo,
  preservation
})
</script>
<template>
  <div>
    <el-steps :space="200" simple>
      <el-step :status="state.active > 0 ? 'success' : 'process'" title="上传文件">上传文件"</el-step>
      <el-step :status="state.active > 1 ? 'success' : (state.active < 1 ? 'wait' : 'process')" title="数据预览">数据预览
      </el-step>
      <el-step :status="state.active > 2 ? 'success' : (state.active < 2 ? 'wait' : 'process')"
               v-if="state.operationType === 'IMPORT'" title="字段配置">字段配置
      </el-step>
      <el-step :status="state.active > 2 ? 'success' : (state.active < 2 ? 'wait' : 'process')"
               v-if="state.operationType === 'CREATE'" title="配置表格">配置表格
      </el-step>
      <el-step :status="state.active > 3 ? 'success' : (state.active < 3 ? 'wait' : 'process')"
               v-if="state.operationType === 'CREATE'" title="设置权限">设置权限
      </el-step>
    </el-steps>
  </div>
  <div style="height: 700px;margin-top: 10px">
    <div v-if="state.active === 0">
      <el-card style="margin: 20px;height: 700px;">
        <CustomUpload
            :uploadSuccess="uploadSuccess"
            :tablePid="table"/>
      </el-card>
    </div>
    <div v-if="state.active === 1">
      <el-card style="margin: 20px;height: 700px;">
        <SelectSheet
            ref="refSelectSheet"
            :excelDomain="state.excelDomain"
            :sheetData="state.importRecordVO.sheetData"
            :importRecordVO="state.importRecordVO"
        />
      </el-card>
    </div>
    <div v-if="state.active === 2">
      <el-card style="margin: 20px;height: 700px;">
        <TableConfigure
            ref="refTable"
            :identity="state.identity"
            :operationType="state.operationType"
            :excelDomain="state.excelDomain"
            :tableInfo="state.tableInfo"
            :fieldInfo="state.fieldInfo"
        />
      </el-card>
    </div>
    <div v-if="state.active === 3">
      <el-card style="margin: 20px;height: 700px;">
        <SetPermission
            :permission="state.permission"
            :administrators="state.administrators"
            :ordinaryUser="state.ordinaryUser"
            ref="refPermission"/>
      </el-card>
    </div>
  </div>
  <div v-if="state.active !== 0" style="margin-top: 10px; text-align: center">
    <el-button @click="upperStep">上一步</el-button>
    <el-button v-if="state.operationType === 'CREATE' ? state.active < 3 : state.active < 2" @click="nextStep"
               type="primary">下一步
    </el-button>
    <el-button v-else @click="preservation" type="primary">保存</el-button>
  </div>
</template>

<style lang="scss" scoped>
.upload-demo {
  ::v-deep .el-upload-dragger {
    width: 1000px;
    height: 400px;
  }

  ::v-deep .el-upload-dragger .el-icon--upload {
    margin: 100px 0 16px;
  }
}
</style>

<route lang="yaml">
meta:
  layout: home
</route>
